using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using NUnit.Framework;
using SCSFContrib.CompositeUI.WPF.UIElements;

namespace SCSFContrib.CompositeUI.WPF.UnitTest.UIElements
{
	[TestFixture]
	public sealed class ItemsControlChildUIAdapterTest : UnitTest
	{
		private ItemsControlChildUIAdapter _itemsControlChildUIAdapter;
		private DependencyObject _dependencyObject;
		private ItemsControl _itemsControl;

		protected override void SetUpCore()
		{
			base.SetUpCore();
			_dependencyObject = new MenuItem();
			_itemsControl = new ItemsControl();
			_itemsControl.Items.Add(_dependencyObject);
			_itemsControlChildUIAdapter = new ItemsControlChildUIAdapter(_dependencyObject);
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void Constructor_ShouldThrowIfItemsControlIsNull()
		{
			new ItemsControlChildUIAdapter(null);
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void Add_ShouldThrowIfItemIsNull()
		{
			_itemsControlChildUIAdapter.Add(null);
		}

		[Test]
		[ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "The DependencyObject wrapped by this ItemsControlChildUIAdapter is not being hosted inside an ItemsControl so it cannot be adapted.")]
		public void Add_ShouldThrowIfNotHostedInItemsControl()
		{
			_itemsControl.Items.Remove(_dependencyObject);
			_itemsControlChildUIAdapter.Add(new DependencyObject());
		}

		[Test]
		public void Add_ShouldInsertTheGivenItemAfterTheDependencyObjectBeingAdapted()
		{
			MenuItem menuItem1 = new MenuItem();
			MenuItem menuItem2 = new MenuItem();

			_itemsControlChildUIAdapter.Add(menuItem1);
			Assert.AreEqual(1, _itemsControl.Items.IndexOf(menuItem1));

			_itemsControl.Items.Add(new MenuItem());

			_itemsControlChildUIAdapter.Add(menuItem2);
			Assert.AreEqual(1, _itemsControl.Items.IndexOf(menuItem2));
			Assert.AreEqual(2, _itemsControl.Items.IndexOf(menuItem1));
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void Remove_ShouldThrowIfItemIsNull()
		{
			_itemsControlChildUIAdapter.Remove(null);
		}

		[Test]
		public void Remove_ShouldNotThrowIfNotHostedInItemsControl()
		{
			_itemsControl.Items.Remove(_dependencyObject);
			_itemsControlChildUIAdapter.Remove(new DependencyObject());
		}

		[Test]
		public void Remove_ShouldDoNothingIfItemIsNotInItemsControl()
		{
			MenuItem menuItem = new MenuItem();

			Assert.IsFalse(_itemsControl.Items.Contains(menuItem));
			_itemsControlChildUIAdapter.Remove(menuItem);
			Assert.IsFalse(_itemsControl.Items.Contains(menuItem));
		}

		[Test]
		public void Remove_ShouldRemoveSpecifiedItemFromItemsControl()
		{
			MenuItem menuItem = new MenuItem();
			_itemsControlChildUIAdapter.Add(menuItem);

			Assert.IsTrue(_itemsControl.Items.Contains(menuItem));
			_itemsControlChildUIAdapter.Remove(menuItem);
			Assert.IsFalse(_itemsControl.Items.Contains(menuItem));
		}
	}
}
